﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TinyPG
{



    /**
     * Classe document qui stockera l'ensemble du texte, et des différentes informations nécessaires 
     * 
     */
    public class Document
    {
        //
        public static Document Doc = new Document();

        public List<string> CartesArd = new List<string>();

        //Liste des chaine de caractères
        public string includes = "";
        public string Declaration = "";
        public string Dec_Defines = "";
        public string Dec_PrototypesFonctions = "";
        public string Dec_Variables = "";
        public string Dec_Var_Receptivites = "";
        public string Dec_Var_Etapes = "";
        public string Dec_Var_EntreesSorties = "";
        public string Dec_Var_Timers = "";
        public string Dec_Var_Memoire = "";

        public string GestionInterruption = "";
        public string GestionInterruption_DecVar = "";

        public string Setup = "";
        public string Setup_ConfigurationTimer = "";
        public string Setup_Initialisations = "";
        public string Setup_Init_Timers = "";
        public string Setup_Init_EtatsPrecedents = "";
        public string Setup_Init_TableauxVar = "";
        public string Setup_Init_Sorties = "";
        public string Setup_Init_Sort_Valeurs = "";
        public string Setup_Init_Sort_Ports = "";
        public string Setup_Init_Entrees = "";
        public string Setup_Init_Ent_Valeurs = "";
        public string Setup_Init_Ent_Ports = "";
        public string Setup_Init_HautesImpedences = "";
        public string Setup_Init_Etapes = "";
        public string Setup_Init_Memoire = "";
        public string Setup_Init_InitTimer = "";
        public string Setup_Init_EnaInitTimer = "";

        public string Loop = "";
        public string Loop_LectureEntrees = "";
        public string Loop_MAJReceptivites = "";
        public string Loop_AppelStructureG7 = "";
        public string Loop_MAJSorties = "";
        public string Loop_EcritureSorties = "";
        public string Loop_MAJEtatsPrecedents;

        public string DefinitionFonctions = "";
        public string DefFct_StructureG7 = "";
        public string DefFct_StructureG7_Debut = "";
        public string DefFct_StructureG7_MAJReceptivites = "";
        public string DefFct_StructureG7_ANTIINFINI = "";
        public string DefFct_StructureG7_Dvlpmt = "";
        public string DefFct_StructureG7_Fin = "";
        public string DefFct_SetByte = "";
        public string DefFct_GetByte = "";
        public string DefFct_CopyTab = "";
        public string DefFct_InitTab = "";
        public string DefFct_FrontMont = "";
        public string DefFct_FrontDesc = "";

        public string Main = "";

        public string ProgrammeFinal = "";
        //Fin Liste des chaine de caractères

        //Variable permettant de mémoriser le prochain emplacement d'un éléments
        public int nextEtapeByte = 0;
        public int nextEtapeBit = 0;

        public int nextInOutByte = 0;
        public int nextInOutBit = 0;

        public int nextMemByte = 0;


        //Dictionnaire regroupant l'ensemble des informations nécessaires à l'évaluation de l'arbre
        public Dictionary<string, Etape> DicoEtape;
        public Dictionary<string, InOut> DicoInOut;
        public Dictionary<string, Receptivite> DicoRecep;
        public Dictionary<string, int> dicoMem;

        public List<Branche> _listeLesBranches;

        public List<string> _listeActions;
        public List<string> _listeEtapeAssocie;

        public List<string> _listeRecep;
        public List<string> _listeEquaAssocie;

        //Constructeur
        public Document()
        {
            //Instanciation des dictionnaires
            DicoEtape = new Dictionary<string, Etape>();
            DicoInOut = new Dictionary<string, InOut>();
            DicoRecep = new Dictionary<string, Receptivite>();
            dicoMem = new Dictionary<string, int>();
            _listeLesBranches = new List<Branche>();

            _listeActions = new List<string>();
            _listeEtapeAssocie = new List<string>();

            _listeRecep = new List<string>();
            _listeEquaAssocie = new List<string>();

            CartesArd.Add("Arduino Uno R3");



            //Tableau permettant l'utilisation de for 
            string[] NomPort = new string[] { "B", "C", "D" };
            int i = 0;

            //////Remplissage de l'ensemble des éléments qui ne varient pas d'un grafcet à l'autre///////////
            includes += "#include <stdlib.h>\r\n";
            includes += "#include <avr/io.h>\r\n";
            includes += "#include <avr/interrupt.h>\r\n\r\n";


            //---Debut Dec_Defines
            Dec_Defines += "#define ENTREE 0\r\n";
            Dec_Defines += "#define ETAPE 1\r\n";
            Dec_Defines += "#define MEMOIRE 2\r\n";
            //---Fin Dec_Defines

            Main += "int main(){\r\n\tsetup();\r\n\twhile(1){\r\n\t\tloop();\r\n\t}\r\n\treturn 0;\r\n}\r\n";

            //---Debut Dec_PrototypesFonctions
            Dec_PrototypesFonctions += "void setup();\r\n";
            Dec_PrototypesFonctions += "void loop();\r\n";
            Dec_PrototypesFonctions += "void structure_G7();\r\n";
            Dec_PrototypesFonctions += "void set_Bit(volatile char* p, int num_case, char num_Bit, char valeur);\r\n";
            Dec_PrototypesFonctions += "char get_Bit(volatile char* p,int num_case, char num_Bit);\r\n";
            Dec_PrototypesFonctions += "void copyTab(volatile char* tabSrc,volatile char* tabDst,int dim);\r\n";
            Dec_PrototypesFonctions += "void initTab(volatile char* p, int dim, char val);\r\n";
            Dec_PrototypesFonctions += "char FrontMont(char Tab, int num_case, char num_Bit);\r\n";
            Dec_PrototypesFonctions += "char FrontDesc(char Tab, int num_case, char num_Bit);\r\n";
            //---Fin Dec_PrototypesFonctions

            //------Debut Dec_Var_EntreesSorties
            Dec_Var_EntreesSorties += "volatile char CopyPIN[3];\r\n";
            Dec_Var_EntreesSorties += "volatile char CmdSort[3];\r\n";
            Dec_Var_EntreesSorties += "volatile char EntreePrec[3];\r\n";
            Dec_Var_EntreesSorties += "volatile char SORT[3];\r\n";
            Dec_Var_EntreesSorties += "volatile char ENT[3];\r\n";
            //------Fin Dec_Var_EntreesSorties

            //---Debut Setup_ConfigurationTimer
            Setup_ConfigurationTimer += "\tcli();\r\n";
            Setup_ConfigurationTimer += "\tTCCR2A = 0B010;";
            Setup_ConfigurationTimer += "\r\n\tOCR2A = 156;";
            Setup_ConfigurationTimer += "\r\n\tTCCR2B = 0B111;";
            Setup_ConfigurationTimer += "\r\n\tTIMSK2 = 0B010;\r\n";
            //---Debut Setup_ConfigurationTimer

            //------Debut Setup_Init_EtatsPrecedents
            for (i = 0; i < 3; i++)
            {
                Setup_Init_EtatsPrecedents += "\tEntreePrec[" + i + "] = PIN" + (char)(i + 'B') + ";\r\n";
            }
            //------Fin Setup_Init_EtatsPrecedents

            //------Debut Setup_Init_TableauxVar
            for (i = 0; i < 3; i++)
                Setup_Init_TableauxVar += "\tinitTab(CmdSort, 3, 0);\r\n";
            Setup_Init_TableauxVar += "\tinitTab(SORT, 3, 0);\r\n";
            Setup_Init_TableauxVar += "\tinitTab(ENT, 3, 255);\r\n";
            //------Fin Setup_Init_TableauxVar

            Setup_Init_EnaInitTimer += "\tsei();\r\n";

            //------Debut Setup_Init_Sort_Ports
            for (i = 0; i < 3; i++)
            {
                Setup_Init_Sort_Ports += "\tDDR" + NomPort[i] + " |= SORT[" + i + "];\r\n";
            }
            //------Fin Setup_Init_Sort_Ports

            //------Debut Setup_Init_Ent_Ports
            for (i = 0; i < 3; i++)
            {
                Setup_Init_Ent_Ports += "\tDDR" + NomPort[i] + " &= ENT[" + i + "];\r\n";
            }
            //------Fin Setup_Init_Ent_Ports

            //------Debut Setup_Init_Etapes
            Setup_Init_Etapes += "\tinitTab(tab_etape,dim_tab_etape,0);\r\n";
            //------Fin Setup_Init_Etapes

            //------Debut Loop_LectureEntrees
            for (i = 0; i < 3; i++)
            {
                Loop_LectureEntrees += "\tCopyPIN[" + i + "] = PIN" + (char)(i + 'B') + ";\r\n";
            }
            //------Fin Loop_LectureEntrees

            //------Debut Loop_MAJEtatsPrecedents
            for (i = 0; i < 3; i++)
            {
                Loop_EcritureSorties += "\tPORT" + NomPort[i] + " = (PORT" + NomPort[i] + " & (~SORT[" + i + "])) | (SORT[" + i + "] &  CmdSort[" + i + "]);\r\n";
            }
            //------Fin Loop_EcritureSorties

            //------Debut Loop_MAJEtatsPrecedents
            Loop_MAJEtatsPrecedents += "\tcopyTab(CopyPIN, EntreePrec, 3);\r\n";
            //------Fin Loop_MAJEtatsPrecedents

            //------Début DefFct_StructureG7_Debut
            DefFct_StructureG7_Debut += "void structure_G7()\r\n";
            DefFct_StructureG7_Debut += "{\r\n";
            DefFct_StructureG7_Debut += "\tcopyTab(tab_etape,Etat_fin,dim_tab_etape);\r\n";
            DefFct_StructureG7_Debut += "\tcopyTab(tab_etape,F_etape,dim_tab_etape);\r\n";
            DefFct_StructureG7_Debut += "\tchar diff;\r\n";
            DefFct_StructureG7_Debut += "\tdo{\r\n";
            //------Fin DefFct_StructureG7_Debut
            DefFct_StructureG7_ANTIINFINI = "\t\tif(";

            //------Début DefFct_StructureG7_Dvlpmt
            DefFct_StructureG7_Dvlpmt += "\t\tcopyTab(Etat_fin,Copie_etape,dim_tab_etape);\r\n";
            DefFct_StructureG7_Dvlpmt += "\t\tdiff = false;\r\n";
            //------Fin DefFct_StructureG7_Dvlpmt

            //------Début DefFct_StructureG7_Fin
            DefFct_StructureG7_Fin += "\t\t int j = 0;\r\n";
            DefFct_StructureG7_Fin += "\t\t do{\r\n";
            DefFct_StructureG7_Fin += "\t\t\tdiff = Copie_etape[j] != Etat_fin[j];\r\n";
            DefFct_StructureG7_Fin += "\t\t\tj++;\r\n";
            DefFct_StructureG7_Fin += "\t\t}while (j<dim_tab_etape && diff == false);\r\n";
            DefFct_StructureG7_Fin += "\t}while(diff);\r\n";
            DefFct_StructureG7_Fin += "\tcopyTab(Etat_fin,tab_etape,dim_tab_etape);\r\n";
            //DefFct_StructureG7_Fin += "\tcopyTab(tab_etape,Copie_etape,dim_tab_etape);\r\n";
            DefFct_StructureG7_Fin += "}\r\n";
            //------Fin DefFct_StructureG7_Fin

            //------Debut de la Définition des Fonctions
            DefFct_SetByte = "void set_Bit(volatile char* p, int num_case, char num_Bit, char valeur){\r\n\tif (valeur){\r\n\t\tp[num_case] |= 1<<num_Bit;\r\n\t\treturn;\r\n\t}\r\n\telse if  (!valeur){\r\n\t\tp[num_case] &= ~(1<<num_Bit);\r\n\t\treturn;\r\n\t}\r\n}\r\n";
            DefFct_GetByte += "char get_Bit(volatile char* p,int num_case, char num_Bit){\r\n\treturn (p[num_case]>>num_Bit) & 0x0001;\r\n}\r\n";
            DefFct_CopyTab += "void copyTab(volatile char* tabSrc,volatile char* tabDst,int dim){\r\n\tfor(int i = 0; i < dim; i++){\r\n\t\ttabDst[i]=tabSrc[i];\r\n\t}\r\n}\r\n";
            DefFct_InitTab += "void initTab(volatile char* p, int dim, char val){\r\n\tfor (int i = 0; i < dim ; i++ ){\r\n\t\tp[i]=val;\r\n\t}\r\n}\r\n";
            DefFct_FrontMont += "char FrontMont(char Tab, int num_case, char num_Bit){\r\n\tswitch(Tab){\r\n\t\tcase ENTREE : \r\n\t\t\treturn ((get_Bit(EntreePrec,num_case,num_Bit) == 0) && (get_Bit(CopyPIN,num_case,num_Bit) == 1));\r\n\t\t\tbreak;\r\n\t\tcase ETAPE : \r\n\t\t\treturn ((get_Bit(F_etape,num_case,num_Bit) == 0) && (get_Bit(Etat_fin,num_case,num_Bit) == 1));\r\n\t\t\tbreak;\r\n" + (dicoMem.Count > 0 ? "\t\tcase MEMOIRE :\r\n\t\t\treturn ((get_Bit(MemPrec,num_case,num_Bit) == 0) && (get_Bit(tab_Mem,num_case,num_Bit) == 1));\r\n\t\t\tbreak;\r\n" : "") + "\t\tdefault : \r\n\t\t\treturn false; \r\n\t}\r\n}\r\n";
            DefFct_FrontDesc += "char FrontDesc(char Tab, int num_case, char num_Bit){\r\n\tswitch(Tab){\r\n\t\tcase ENTREE : \r\n\t\t\treturn ((get_Bit(EntreePrec,num_case,num_Bit) == 1) && (get_Bit(CopyPIN,num_case,num_Bit) == 0));\r\n\t\t\tbreak;\r\n\t\tcase ETAPE : \r\n\t\t\treturn ((get_Bit(F_etape,num_case,num_Bit) == 1) && (get_Bit(Etat_fin,num_case,num_Bit) == 0));\r\n\t\t\tbreak;\r\n" + (dicoMem.Count > 0 ? "\t\tcase MEMOIRE :\r\n\t\t\treturn ((get_Bit(MemPrec,num_case,num_Bit) == 1) && (get_Bit(tab_Mem,num_case,num_Bit) == 0));\r\n\t\t\tbreak;\r\n" : "") + "\t\tdefault : \r\n\t\t\treturn false; \r\n\t}\r\n}\r\n";
            //------Fin de la Définition des Fonctions

        }




        //Certains ajout nécessite de connaitre la présence de certains éléments
        //Cette fonction est donc appelé après l'évaluation complète de l'arbre 
        //afin de rajouter les éléments qui dépendent du grafcet
        public void finalChange()
        {
            //Déclaration des étapes avec dimensionnement
            Dec_Var_Etapes += "volatile int NB_etapes = " + DicoEtape.Count.ToString() + ";\r\n";
            Dec_Var_Etapes += "volatile int dim_tab_etape = ((int)(NB_etapes /8)+1);";
            Dec_Var_Etapes += "volatile char* tab_etape = (volatile char * )malloc(dim_tab_etape);\r\n";
            Dec_Var_Etapes += "volatile char* Copie_etape = (volatile char * )malloc(dim_tab_etape);\r\n";
            Dec_Var_Etapes += "volatile char* F_etape = (volatile char * )malloc(dim_tab_etape);\r\n";
            Dec_Var_Etapes += "volatile char* Etat_fin = (volatile char * )malloc(dim_tab_etape);\r\n";

            //Si l'utilisateur utilise des mots mémoires on les déclare ici
            if (dicoMem.Count > 0)
            {
                Dec_Var_Memoire += "volatile int NB_Mot_MEM = " + dicoMem.Count.ToString() + ";\r\n";
                Dec_Var_Memoire += "volatile char* tab_Mem = (volatile char * )malloc(dim_tab_etape);\r\n";
                Dec_Var_Memoire += "volatile char* MemPrec = (volatile char * )malloc(dim_tab_etape);\r\n";
            }

            //Doit être placé à la fin de leurs chaines recpective
            Setup_Init_Etapes += "\tcopyTab(tab_etape,Copie_etape,dim_tab_etape);\r\n";
            Setup_Init_Etapes += "\tcopyTab(tab_etape,F_etape,dim_tab_etape);\r\n";

            DefFct_StructureG7_ANTIINFINI += "1)\r\n\t\t\treturn;\r\n";
        }

        public void PositionnerBranches()
        {
            /*De Haut en Bas
             * set ymin = max(prec(ymin)+size))
             * set a = somme prec(a)
             */
            _listeLesBranches[_listeLesBranches.Count - 2]._Ymin = 0;
            _listeLesBranches[_listeLesBranches.Count - 2]._a = 1;
            _listeLesBranches[_listeLesBranches.Count - 2].Set_Ymin_a();

            /*De bas en Haut
             * set ymax = min(prec(ymax)+size)
             * set b = somme (prec(b))
             * calcule largeur = a*b
             */
            _listeLesBranches[_listeLesBranches.Count - 1]._Ymax = _listeLesBranches[_listeLesBranches.Count - 1]._Ymin;
            _listeLesBranches[_listeLesBranches.Count - 1]._b = 1;

            _listeLesBranches[_listeLesBranches.Count - 1].Set_Ymax_b();


            _listeLesBranches[_listeLesBranches.Count - 2]._c = Math.Max(_listeLesBranches[_listeLesBranches.Count - 2]._a, _listeLesBranches[_listeLesBranches.Count - 2]._b);
            _listeLesBranches[_listeLesBranches.Count - 2].Set_c();


            _listeLesBranches[_listeLesBranches.Count - 1]._d = Math.Max(_listeLesBranches[_listeLesBranches.Count - 1]._a, _listeLesBranches[_listeLesBranches.Count - 1]._b);
            _listeLesBranches[_listeLesBranches.Count - 1]._Largeur = Math.Max(_listeLesBranches[_listeLesBranches.Count - 1]._c, _listeLesBranches[_listeLesBranches.Count - 1]._d);
            _listeLesBranches[_listeLesBranches.Count - 1].Set_d();
            /*de haut en bas
             * set ypos = min(prec(ypos)+size)
             */
            /*
            _listeLesBranches[_listeLesBranches.Count - 2]._Yint = 0;
            _listeLesBranches[_listeLesBranches.Count - 2].Set_Yint();
            */
            /*De bas en Haut
              * set ypos = min(prec(ypos)+size)
              */

            _listeLesBranches[_listeLesBranches.Count - 2]._Ypos = _listeLesBranches[_listeLesBranches.Count - 2]._Ymin;
            int MinIdx = -1;
            int MinVal;

            do
            {
                MinIdx = -1;
                MinVal = _listeLesBranches[_listeLesBranches.Count - 1]._Ymax;
                foreach (Branche B in _listeLesBranches[_listeLesBranches.Count - 2]._listBrancheNext)
                {
                    if (B._Ymax < MinVal && B._Ypos == -1)
                    {
                        MinIdx = _listeLesBranches[_listeLesBranches.Count - 2]._listBrancheNext.IndexOf(B);
                        MinVal = B._Ymax;
                    }
                }
                if (MinIdx > -1)
                {
                    _listeLesBranches[_listeLesBranches.Count - 2]._listBrancheNext[MinIdx]._Ypos = _listeLesBranches[_listeLesBranches.Count - 2]._listBrancheNext[MinIdx]._Ymin;
                    _listeLesBranches[_listeLesBranches.Count - 2]._listBrancheNext[MinIdx].Set_Ypos();
                }

            } while (MinIdx > -1);


            /*gauche a droite
             * set xmin xpos 
             */
            _listeLesBranches[_listeLesBranches.Count - 2]._Xmin = 1;
            _listeLesBranches[_listeLesBranches.Count - 2]._Xint = _listeLesBranches[_listeLesBranches.Count - 2]._Xmin + (_listeLesBranches[_listeLesBranches.Count - 2]._Largeur - _listeLesBranches[_listeLesBranches.Count - 2]._nbCase) / 2;
            _listeLesBranches[_listeLesBranches.Count - 2].Set_Xmin_Xint();

            _listeLesBranches[_listeLesBranches.Count - 1]._Xpos = _listeLesBranches[_listeLesBranches.Count - 1]._Xint;
            _listeLesBranches[_listeLesBranches.Count - 1].Set_Xpos();

        }

        public void Structurer()
        {
            int i = 0;
            while (_listeActions.IndexOf(i.ToString()) > -1)
            {
                int kFin;
                if (_listeActions.IndexOf((i + 1).ToString()) > -1)
                {
                    kFin = _listeEtapeAssocie.IndexOf((i + 1).ToString());
                }
                else
                {
                    kFin = _listeEtapeAssocie.Count;
                }

                for (int kDeb = _listeEtapeAssocie.IndexOf(i.ToString()) + 1; kDeb < kFin; kDeb++)
                {
                    DicoEtape[_listeEtapeAssocie[kDeb]]._listActions.Add(_listeActions[_listeActions.IndexOf(i.ToString())+1]);
                }
                i++;
            }

            

            Branche BrDebut = new Branche(false);

            foreach (string key in DicoEtape.Keys)
            {
                if (DicoEtape[key].GetInit() == true)
                {
                    Branche BrancheNoeud = new Branche(true);
                    BrDebut.AddBrancheNext(BrancheNoeud);
                    BrancheNoeud.AddBranchePrev(BrDebut);

                    Branche B = new Branche(false);
                    BrancheNoeud.AddBrancheNext(B);
                    B.AddBranchePrev(BrancheNoeud);

                    _listeLesBranches.Add(BrancheNoeud);

                    B.AddElement(DicoEtape[key]);
                    DicoEtape[key].AppartientA(B);
                    _listeLesBranches.Add(B);
                }
            }
            foreach (string key in DicoEtape.Keys)
            {
                if (DicoEtape[key].GetInit() == true)
                {
                    DicoEtape[key].DefineStructure();

                }
            }





            Branche BrFin = new Branche(false);
            List<Branche[]> BrancheNextBranche = new List<Branche[]>();
            List<Branche[]> BrancheAAjouterAvant = new List<Branche[]>();

            foreach (Branche B in _listeLesBranches)
            {
                foreach (Branche BrNext in B._listBrancheRetourAval)
                {
                    List<Branche> BranchesParcourues = new List<Branche>();
                    if (!BrNext._listElements[0].GetInit())
                    {
                        if (!BrNext.Rechercher(B, BranchesParcourues))
                        {
                            BrancheNextBranche.Add(new Branche[] { B, BrNext });
                        }
                        else
                        {
                            BrancheAAjouterAvant.Add(new Branche[] {B,BrNext});
                        }
                    }

                }
            }
            foreach (Branche[] BB in BrancheNextBranche)
            {
                BB[0]._listBrancheNext.Add(BB[1]);
                BB[1]._listBranchePrev.Add(BB[0]);

                BB[1]._listBrancheRetourAmont.Remove(BB[0]);
                BB[0]._listBrancheRetourAval.Remove(BB[1]);
            }

            foreach (Branche[] BB in BrancheAAjouterAvant)
            {
                Branche Br = new Branche(true);
                Br._listBranchePrev.Add(BrDebut);
                BrDebut._listBrancheNext.Add(Br);

                Br._listBrancheNext.Add(BB[1]);
                BB[1]._listBranchePrev.Add(Br);

                BB[1]._listBrancheRetourAmont.Remove(BB[0]);
                BB[0]._listBrancheRetourAval.Remove(BB[1]);

                Br._listBrancheRetourAmont.Add(BB[0]);
                BB[0]._listBrancheRetourAval.Add(Br);


                _listeLesBranches.Add(Br);
            }

            List<Branche> _listBrancheRetourAAdd = new List<Branche>();
            foreach (Branche B in _listeLesBranches)
            {
                if (B._listBrancheRetourAmont.Count > 0)
                {
                    Branche BAval = new Branche(false);
                    //Branche BNoeud =new Branche(true);
                    BAval._listBrancheNext.Add(BrFin);
                    BrFin._listBranchePrev.Add(BAval);

                    BAval._listBrancheRetourAval.Add(B);
                    foreach (Branche BRetour in B._listBrancheRetourAmont)
                    {
                        BRetour._listBrancheRetourAval.Remove(B);
                        BRetour._listBrancheNext.Add(BAval);
                        BAval._listBranchePrev.Add(BRetour);
                    }
                    B._listBrancheRetourAmont.Clear();
                    B._listBrancheRetourAmont.Add(BAval);

                    _listBrancheRetourAAdd.Add(BAval);
                }
            }
            foreach (Branche B in _listBrancheRetourAAdd)
            {
                _listeLesBranches.Add(B);
            }


            BrDebut._beginEnd = true;
            _listeLesBranches.Add(BrDebut);
            BrFin._beginEnd = true;
            _listeLesBranches.Add(BrFin);

            foreach (Branche B in _listeLesBranches)
            {
                B.SetLargeur();
            }

            PositionnerBranches();
        }


        //Méthode qui réalise la concaténation de l'ensemble des autres chaines

        public override string ToString()
        {
            //Dernier changement avant concaténation
            finalChange();

            /*=====Structure du programme=====
            Déclaration
                Fonctions
                Variables
                    Transitions
                    Etapes
                    Entrées/Sorties
                    Timer
            Gestion interruption
            Setup
                Configuration du timer
                Initialisations
                    timer
                    Etats précédents
                    Tableaux de variables
                    Sorties
                        Valeurs
                        Ports
                    Entrée
                        Valeur
                        Ports
                    Hautes Impédences
                    Etape
            Loop
                Lectures des Entrées
                appel StructureG7
                Mise à Jour des sorties
                Ecriture des sorties
                Mise à jour des états des précédents
            Fonction
                Fonction Structure G7
                    Debut
                    MAJReceptivites
                    Dvlpmt
                    StructureG7_Fin             
               set_Byte
               Get_Byte
               copy_Tab
               init_Tab
               FrontMont
               FrontDesc
            =====Fin Structure Programme=====*/


            //Ecriture du Programme
            //Début Bloc Declaration
            ProgrammeFinal += includes;
            ProgrammeFinal += "//===========Début des Déclarations===========\r\n";

            Declaration += "//----Début des define----\r\n";
            Declaration += Dec_Defines;
            Declaration += "//----Fin des define----\r\n\r\n";

            Declaration += "//----Début de la Déclaration du Prototype des Fonctions----\r\n";
            Declaration += Dec_PrototypesFonctions;
            Declaration += "//----Fin de la Déclaration du Prototype des Fonctions----\r\n\r\n";

            Declaration += "//----Début de la Déclaration des Variables----\r\n";
            //---Debut Dec_Variables
            Dec_Variables += "//--------Début Variables des Réceptivites--------\r\n";
            Dec_Variables += Dec_Var_Receptivites;
            Dec_Variables += "//--------Fin Variables des Réceptivites--------\r\n\r\n";
            Dec_Variables += "//--------Début Variables Etapes--------\r\n";
            Dec_Variables += Dec_Var_Etapes;
            Dec_Variables += "//--------Fin Variables Etapes--------\r\n\r\n";
            Dec_Variables += "//--------Début Variables Mémoires--------\r\n";
            Dec_Variables += Dec_Var_Memoire;
            Dec_Variables += "//--------Fin Variables Mémoires--------\r\n\r\n";
            Dec_Variables += "//--------Début Variables d'Entrées/Sorties--------\r\n";
            Dec_Variables += Dec_Var_EntreesSorties;
            Dec_Variables += "//--------Fin Variables d'Entrées/Sorties--------\r\n\r\n";
            Dec_Variables += "//--------Début Variables Timers--------\r\n";
            Dec_Variables += Dec_Var_Timers;
            Dec_Variables += "//--------Fin Variables Timers--------\r\n";
            //---Fin Dec_Variables
            Declaration += Dec_Variables;
            Declaration += "//----Fin de la Déclaration des Variables----\r\n";

            ProgrammeFinal += Declaration;
            ProgrammeFinal += "//===========Fin des Déclarations===========\r\n\r\n";
            //Fin Bloc Declaration

            //Début Bloc GestionInterruption
            ProgrammeFinal += "//===========Début de la Gestion des Interruptions===========\r\n";

            GestionInterruption += "ISR(TIMER2_COMPA_vect)\r\n{\r\n";
            GestionInterruption += GestionInterruption_DecVar;
            GestionInterruption += "}\r\n";

            ProgrammeFinal += GestionInterruption;
            ProgrammeFinal += "//===========Fin de la Gestion des Interruptions===========\r\n\r\n";
            //Fin Bloc GestionInterruption

            ProgrammeFinal += Main;

            //Début Bloc Setup
            ProgrammeFinal += "//===========Début du Setup===========\r\n";
            Setup += "void setup()\r\n{\r\n";
            Setup += "//----Début de la Configuration des Timers----\r\n";
            Setup += Setup_ConfigurationTimer;
            Setup += "//----Fin de la Configuration des Timers----\r\n\r\n";

            Setup += "//----Début des Initialisations----\r\n";
            //---Debut Setup_Initialisations
            Setup_Initialisations += "//--------Début de l'Initialisation des Timers-------\r\n";
            Setup_Initialisations += Setup_Init_Timers;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Timers-------\r\n";

            Setup_Initialisations += "//--------Début de l'nitialisation des Etats Précédents-------\r\n";
            Setup_Initialisations += Setup_Init_EtatsPrecedents;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Etats Précédents-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des Tableaux de Variables-------\r\n";
            Setup_Initialisations += Setup_Init_TableauxVar;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Tableaux de Variables-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des Sorties (Valeurs et Ports)-------\r\n";
            Setup_Init_Sorties += Setup_Init_Sort_Valeurs;
            Setup_Init_Sorties += Setup_Init_Sort_Ports;
            Setup_Initialisations += Setup_Init_Sorties;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Sorties (Valeurs et Ports)-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des Entrées (Valeurs et Ports)-------\r\n";
            Setup_Init_Entrees += Setup_Init_Ent_Valeurs;
            Setup_Init_Entrees += Setup_Init_Ent_Ports;
            Setup_Initialisations += Setup_Init_Entrees;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Entrées (Valeurs et Ports)-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des Hautes Impédences-------\r\n";
            Setup_Initialisations += Setup_Init_HautesImpedences;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Hautes Impédences-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des Etapes-------\r\n";
            Setup_Initialisations += Setup_Init_Etapes;
            Setup_Initialisations += "//--------Fin de l'Initialisation des Etapes-------\r\n";

            Setup_Initialisations += "//--------Début de l'Initialisation des mots mémoires-------\r\n";
            Setup_Initialisations += Setup_Init_Memoire;
            Setup_Initialisations += "//--------Fin de l'Initialisation des mots mémoires-------\r\n";

            Setup_Initialisations += Setup_Init_InitTimer;
            Setup_Initialisations += Setup_Init_EnaInitTimer;
            //---Fin Setup_Initialisations

            Setup += Setup_Initialisations;
            Setup += "//----Fin des Initialisations----\r\n";
            Setup += "}\r\n";

            ProgrammeFinal += Setup;
            ProgrammeFinal += "//===========Fin du Setup===========\r\n\r\n";
            //Fin Bloc Setup

            //Début Bloc Loop
            ProgrammeFinal += "//===========Début du Loop===========\r\n";

            Loop += "void loop()\r\n{\r\n";
            Loop += "//----Début de la Lecture des Entrées----\r\n";
            Loop += Loop_LectureEntrees;
            Loop += "//----Fin de la Lecture des Entrées----\r\n";

            Loop += "//----Début de la Mise à Jour de l'état des Réceptivité----\r\n";
            Loop += Loop_MAJReceptivites;
            Loop += "//----Fin de la Mise à Jour de l'état des Réceptivité----\r\n";

            Loop += "//----Début de l'appel de la fonction StructureG7----\r\n";
            Loop_AppelStructureG7 += "\tstructure_G7();\r\n";
            Loop += Loop_AppelStructureG7;
            Loop += "//----Fin de l'appel de la fonction StructureG7----\r\n";

            Loop += "//----Début de la Mise à Jour des Sorties----\r\n";
            Loop += Loop_MAJSorties;
            Loop += "//----Fin de la Mise à Jour des Sorties----\r\n";

            Loop += "//----Début de l'Ecriture des Sorties----\r\n";
            Loop += Loop_EcritureSorties;
            Loop += "//----Fin de l'Ecriture des Sorties----\r\n";

            Loop += "//----Début de la Mise à Jour des Etats Précédents----\r\n";
            Loop += Loop_MAJEtatsPrecedents;
            Loop += "//----Fin de la Mise à Jour des Etats Précédents----\r\n";
            Loop += "}\r\n";

            ProgrammeFinal += Loop;
            ProgrammeFinal += "//===========Fin du Loop===========\r\n\r\n";
            //Fin Bloc Loop



            //Début Bloc DefinitionFonctions
            ProgrammeFinal += "//===========Début de la Définition des Fonctions===========\r\n";

            DefinitionFonctions += "//----Fonction de la StructureG7----\r\n";
            DefFct_StructureG7 += DefFct_StructureG7_Debut;
            DefFct_StructureG7 += DefFct_StructureG7_MAJReceptivites;
            DefFct_StructureG7 += DefFct_StructureG7_ANTIINFINI;
            DefFct_StructureG7 += DefFct_StructureG7_Dvlpmt;
            DefFct_StructureG7 += DefFct_StructureG7_Fin;
            DefinitionFonctions += DefFct_StructureG7;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_SetByte----\r\n";
            DefinitionFonctions += DefFct_SetByte;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_GetByte----\r\n";
            DefinitionFonctions += DefFct_GetByte;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_CopyTab----\r\n";
            DefinitionFonctions += DefFct_CopyTab;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_InitTab----\r\n";
            DefinitionFonctions += DefFct_InitTab;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_FrontMont----\r\n";
            DefinitionFonctions += DefFct_FrontMont;
            DefinitionFonctions += "\r\n//----Fonction de la DefFct_FrontDesc----\r\n";
            DefinitionFonctions += DefFct_FrontDesc;

            ProgrammeFinal += DefinitionFonctions;
            ProgrammeFinal += "//===========Fin de la Définition des Fonctions===========\r\n\r\n";
            //Fin Bloc DefinitionFonctions
            //Fin Ecriture du Programme

            return ProgrammeFinal;
        }
    }
}
